package com.yulei.framework.ioc.core;

import com.yulei.framework.ioc.annotation.IocComponent;
import com.yulei.framework.ioc.bean.BeanDefinition;
import com.yulei.framework.ioc.bean.ConstructorArg;
import com.yulei.framework.ioc.bean.PropertyArg;
import com.yulei.framework.ioc.handle.PackageScanner;
import com.yulei.framework.ioc.utils.ReflectionUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author yulei
 * date 2023/12/22 16:27
 */
public class AnnotationApplicationContext extends BeanFactoryImpl {

    public void init(String packageName) {
        if (packageName == null) {
            return;
        }
        List<Class<?>> classes = PackageScanner.scanPackage(packageName);
        for (Class<?> aClass : classes) {
            if (aClass.isAnnotationPresent(IocComponent.class)) {
                BeanDefinition b = new BeanDefinition();
                // bean name
                // 获取 注解中自定义的 bean名称
                IocComponent annotation = aClass.getAnnotation(IocComponent.class);
                if (annotation != null) {
                    b.setName(!annotation.value().isEmpty() ? annotation.value() : uncapitalize(aClass.getSimpleName()));
                } else {
                    b.setName(uncapitalize(aClass.getSimpleName()));
                }
                // bean 全限定名
                b.setClassName(aClass.getName());
                b.setInterfaceName(aClass.getSuperclass().getName());

                // 设置构造参数
                List<ConstructorArg> constructorArgs = new ArrayList<>();
                Constructor<?>[] constructors = aClass.getConstructors();
                for (Constructor<?> constructor : constructors) {
                    Class<?>[] parameterTypes = constructor.getParameterTypes();
                    if (parameterTypes != null) {
                        for (Class<?> parameterType : parameterTypes) {
                            ConstructorArg constructorArg = new ConstructorArg();
                            constructorArg.setName(parameterType.getSimpleName());
                            constructorArg.setRef(uncapitalize(parameterType.getSimpleName()));
                            constructorArgs.add(constructorArg);
                        }
                    }
                }

                b.setConstructorArgs(constructorArgs);
                // 设置属性
                List<PropertyArg> propertyArgs = new ArrayList<>();
                for (Field field : aClass.getDeclaredFields()) {
                    PropertyArg propertyArg = new PropertyArg();
                    propertyArg.setName(field.getName());
                    propertyArg.setTypeName(field.getType().toString());
                    propertyArgs.add(propertyArg);
                }
                b.setPropertyArgs(propertyArgs);

                registerBean(b.getName(), b);
            }
        }

    }

}
